#include "../log/log.h"
#include <vector>
#include <thread>
#include <chrono>
/*性能测试
    1.测试性能
    2.测试方法
    3.测试结果
*/
void bench(const std::string &logger_name, size_t thr_count, size_t msg_count, size_t msg_len)
{
    // 1.获取日志器
    log::Logger::ptr logger = log::getLogger(logger_name);
    if (logger.get() == nullptr)
        return;
    std::cout << "测试日志：" << msg_count << "条，总大小:" << (msg_count * msg_len) / 1024 << "KB" << std::endl;
    // 2.组织指定长度的日志消息
    std::string msg(msg_len - 1, 'A');
    // 3.创建指定数量的线程
    std::vector<std::thread> threads;
    std::vector<double> cost_arry(thr_count);
    size_t msg_per_thr = msg_count / thr_count; // 每个线程要输出消息的数量

    for (int i = 0; i < thr_count; ++i)
    {
        // 创建对象并插入到vector中
        threads.emplace_back([&, i]()
                             {
            //4.线程函数内部开始计时
            auto start = std::chrono::high_resolution_clock::now();
            //5.开始循环写日志
            for(int j=0;j < msg_per_thr;++j)
            {
                logger->fatal("%s",msg.c_str());
            }
            //6.线程函数内部结束计时
            auto end  = std::chrono::high_resolution_clock::now();
            std::chrono::duration<double> diff = end - start;
            cost_arry[i] = diff.count();
            std::cout << "线程" << i <<": " <<"\t输出数量" << msg_per_thr <<",耗时: " << cost_arry[i] << "s" <<std::endl; });
    }

    for (int i = 0; i < thr_count; ++i)
    {
        threads[i].join();
    }

    // 7.计算总耗时
    double max_cost = cost_arry[0];
    for (int i = 1; i < thr_count; ++i)
    {
        max_cost = cost_arry[i] > max_cost ? cost_arry[i] : max_cost;
    }

    size_t msg_per_sec = msg_count / max_cost;
    size_t size_per_sec = (msg_count * msg_len) / (max_cost * 1024);
    // 8.输出结果
    std::cout << "\t总耗时: " << max_cost << "s\n";
    std::cout << "\t每秒输出日志数量: " << msg_per_sec << "条" << std::endl;
    std::cout << "\t每秒输出日志大小: " << size_per_sec << "KB" << std::endl;
}
//同步写日志（效率和磁盘性能有关）
void sync_bench()
{
    std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder());
    builder->buildLoggerName("sync_logger");
    builder->buildLoggerLevel(log::LogLevel::value::DEBUG);
    builder->buildLoggerType(log::LoggerType::LOGGER_SYNC); // 同步日志器
    builder->buildFormatter("%m%n");
    builder->buildSink<log::FileSink>("./logfile/sync.log");
    builder->build();
    //bench("sync_logger", 1, 1000000, 100);
    bench("sync_logger",3,1000000,100);
}
//异步写日志 （上线和cpu和内存有关）
void async_bench()
{
    std::unique_ptr<log::LoggerBuilder> builder(new log::GlobalLoggerBuilder());
    builder->buildLoggerName("async_logger");
    builder->buildLoggerLevel(log::LogLevel::value::DEBUG);
    builder->buildLoggerType(log::LoggerType::LOGGER_ASYNC);
    builder->buildEnableUnsafeAsync();//开启非完全模式 --将实际落地时间排除
    builder->buildFormatter("%m%n");
    builder->buildSink<log::FileSink>("./logfile/async.log");
    builder->build();
    bench("async_logger", 1, 1000000, 100);
    //bench("async_logger",3,1000000,100);
}

int main()
{
    //sync_bench();
    async_bench();
    return 0;
}